package com.example.testapp.domain.util

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Environment
import android.util.Log
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.text.SimpleDateFormat
import java.util.*

/**
 * 图片存储工具类
 */
object ImageStorageUtil {
    private const val TAG = "ImageStorageUtil"
    
    // 存储目录名称
    private const val APP_DIR = "app_balance"
    private const val IMAGES_DIR = "images"
    private const val THUMBNAILS_DIR = "thumbnails"
    private const val TEMP_DIR = "temp"
    
    // 缩略图尺寸
    private const val THUMBNAIL_WIDTH = 200
    private const val THUMBNAIL_HEIGHT = 200
    
    // 缩略图后缀
    private const val THUMBNAIL_SUFFIX = "_thumb.jpg"
    
    /**
     * 创建临时图片文件
     * @param context 上下文
     * @return 临时图片文件
     * @throws IOException IO异常
     */
    @JvmStatic
    @Throws(IOException::class)
    fun createTempImageFile(context: Context): File {
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val imageFileName = "tmp_${timeStamp}_"
        val storageDir = getTempDirectory(context)
        return File.createTempFile(imageFileName, ".jpg", storageDir)
    }
    
    /**
     * 将图片从Uri保存到临时文件
     * @param context 上下文
     * @param sourceUri 源图片Uri
     * @return 保存的临时文件
     */
    @JvmStatic
    fun saveImageToTemp(context: Context, sourceUri: Uri): File? {
        try {
            val tempFile = createTempImageFile(context)
            context.contentResolver.openInputStream(sourceUri)?.use { inputStream ->
                Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
                return tempFile
            }
        } catch (e: IOException) {
            Log.e(TAG, "Error saving image to temp file", e)
        }
        return null
    }
    
    /**
     * 将临时图片移动到永久存储
     * @param context 上下文
     * @param tempFilePath 临时文件路径
     * @param balanceId 账单ID
     * @return 永久存储的图片路径
     */
    @JvmStatic
    fun moveToPermanentStorage(context: Context, tempFilePath: String, balanceId: Long): String? {
        val tempFile = File(tempFilePath)
        if (!tempFile.exists()) {
            Log.e(TAG, "Temp file does not exist: $tempFilePath")
            return null
        }
        
        // 生成目标路径
        val hashPath = generateHashPath(balanceId)
        val targetDir = File(getImagesDirectory(context), hashPath)
        if (!targetDir.exists() && !targetDir.mkdirs()) {
            Log.e(TAG, "Failed to create target directory: ${targetDir.absolutePath}")
            return null
        }
        
        val fileName = "$balanceId.jpg"
        val targetFile = File(targetDir, fileName)
        
        return try {
            Files.move(tempFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
            targetFile.absolutePath
        } catch (e: IOException) {
            Log.e(TAG, "Error moving file to permanent storage", e)
            null
        }
    }
    
    /**
     * 生成缩略图
     * @param context 上下文
     * @param imagePath 原图路径
     * @param balanceId 账单ID
     * @return 缩略图路径
     */
    @JvmStatic
    fun generateThumbnail(context: Context, imagePath: String, balanceId: Long): String? {
        // 加载原图
        val originalBitmap = BitmapFactory.decodeFile(imagePath)
        if (originalBitmap == null) {
            Log.e(TAG, "Failed to decode original image: $imagePath")
            return null
        }
        
        try {
            // 缩放图像
            val aspectRatio = originalBitmap.width.toFloat() / originalBitmap.height.toFloat()
            val thumbnailWidth: Int
            val thumbnailHeight: Int
            
            if (aspectRatio > 1) {
                thumbnailWidth = THUMBNAIL_WIDTH
                thumbnailHeight = (THUMBNAIL_WIDTH / aspectRatio).toInt()
            } else {
                thumbnailHeight = THUMBNAIL_HEIGHT
                thumbnailWidth = (THUMBNAIL_HEIGHT * aspectRatio).toInt()
            }
            
            val thumbnailBitmap = Bitmap.createScaledBitmap(originalBitmap, thumbnailWidth, thumbnailHeight, true)
            
            // 生成目标路径
            val hashPath = generateHashPath(balanceId)
            val targetDir = File(getThumbnailsDirectory(context), hashPath)
            if (!targetDir.exists() && !targetDir.mkdirs()) {
                Log.e(TAG, "Failed to create thumbnail directory: ${targetDir.absolutePath}")
                return null
            }
            
            val fileName = "$balanceId$THUMBNAIL_SUFFIX"
            val thumbnailFile = File(targetDir, fileName)
            
            // 保存缩略图
            try {
                FileOutputStream(thumbnailFile).use { outputStream ->
                    thumbnailBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
                    return thumbnailFile.absolutePath
                }
            } catch (e: IOException) {
                Log.e(TAG, "Error saving thumbnail", e)
                return null
            } finally {
                // 释放资源
                thumbnailBitmap.recycle()
            }
        } finally {
            // 释放原图资源
            originalBitmap.recycle()
        }
    }
    
    /**
     * 删除临时文件
     * @param filePath 文件路径
     * @return 是否成功删除
     */
    @JvmStatic
    fun deleteTempFile(filePath: String?): Boolean {
        if (filePath == null) {
            return false
        }
        
        val file = File(filePath)
        return file.exists() && file.delete()
    }
    
    /**
     * 清理过期临时文件（超过24小时）
     * @param context 上下文
     */
    @JvmStatic
    fun cleanupTempFiles(context: Context) {
        val tempDir = getTempDirectory(context)
        if (!tempDir.exists()) {
            return
        }
        
        val files = tempDir.listFiles() ?: return
        
        val cutoffTime = System.currentTimeMillis() - (24 * 60 * 60 * 1000) // 24小时前
        
        for (file in files) {
            if (file.lastModified() < cutoffTime) {
                if (!file.delete()) {
                    Log.w(TAG, "Failed to delete old temp file: ${file.absolutePath}")
                }
            }
        }
    }
    
    /**
     * 基于balanceId生成哈希路径（取前两位作为目录名）
     * @param balanceId 账单ID
     * @return 哈希路径
     */
    private fun generateHashPath(balanceId: Long): String {
        return try {
            val idStr = balanceId.toString()
            val md = MessageDigest.getInstance("MD5")
            val digest = md.digest(idStr.toByteArray())
            
            // 取哈希值的前两位字符作为目录名
            val sb = StringBuilder()
            sb.append(String.format("%02x", digest[0]))
            
            sb.toString()
        } catch (e: NoSuchAlgorithmException) {
            Log.e(TAG, "MD5 algorithm not found", e)
            // 回退方案：使用ID的前两位数字
            val idStr = Math.abs(balanceId).toString()
            if (idStr.length > 2) idStr.substring(0, 2) else idStr
        }
    }
    
    /**
     * 获取应用根目录
     * @param context 上下文
     * @return 应用根目录
     */
    private fun getAppDirectory(context: Context): File {
        val dir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), APP_DIR)
        if (!dir.exists() && !dir.mkdirs()) {
            Log.e(TAG, "Failed to create app directory")
        }
        return dir
    }
    
    /**
     * 获取图片存储目录
     * @param context 上下文
     * @return 图片存储目录
     */
    private fun getImagesDirectory(context: Context): File {
        val dir = File(getAppDirectory(context), IMAGES_DIR)
        if (!dir.exists() && !dir.mkdirs()) {
            Log.e(TAG, "Failed to create images directory")
        }
        return dir
    }
    
    /**
     * 获取缩略图存储目录
     * @param context 上下文
     * @return 缩略图存储目录
     */
    private fun getThumbnailsDirectory(context: Context): File {
        val dir = File(getAppDirectory(context), THUMBNAILS_DIR)
        if (!dir.exists() && !dir.mkdirs()) {
            Log.e(TAG, "Failed to create thumbnails directory")
        }
        return dir
    }
    
    /**
     * 获取临时文件存储目录
     * @param context 上下文
     * @return 临时文件存储目录
     */
    private fun getTempDirectory(context: Context): File {
        val dir = File(getAppDirectory(context), TEMP_DIR)
        if (!dir.exists() && !dir.mkdirs()) {
            Log.e(TAG, "Failed to create temp directory")
        }
        return dir
    }
} 